package com.dragons.spring5;

import com.dragons.spring5.autowired.Emp1;
import com.dragons.spring5.bean_life.Order1;
import com.dragons.spring5.beans.Emp;
import com.dragons.spring5.collectiontype.Course;
import com.dragons.spring5.collectiontype.Library;
import com.dragons.spring5.collectiontype.Stu;
import com.dragons.spring5.collectiontype.Stu1;
import com.dragons.spring5.factory_bean.MyBean;
import com.dragons.spring5.service.UserService;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {

    @Test //添加的时候要设置一下Maven 不然会添加失败
    public void testAdd(){
        //加载spring配置文件
        //ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        User user=context.getBean("user",User.class);
        System.out.println(user);
        user.add();
    }

    @Test //测试set方式注入属性
    public void testSetDI(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Book book=(Book)context.getBean("book",Book.class);
        System.out.println(book);
    }

    @Test //测试注入外部bean
    public void testDIOutsideBean(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        UserService userService=(UserService)context.getBean("userService",UserService.class);
        userService.add1();
    }


    @Test //内部bean
    public void testDIInsideBean(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Emp emp=(Emp)context.getBean("emp",Emp.class);
        System.out.println(emp);
    }


    @Test //级联赋值 第一种
    public void testDIInsideBean1(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Emp emp=(Emp)context.getBean("emp1",Emp.class);
        System.out.println(emp);
    }

    @Test //级联赋值 第二种
    public void testDIInsideBean2(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Emp emp=(Emp)context.getBean("emp2",Emp.class);
        System.out.println(emp);
    }




    @Test //测试集合属性的注入和配置
    public void testInsertCollectionBean(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Stu stu=context.getBean("stu",Stu.class);
        System.out.println(stu);
    }


    @Test //细节处理-在集合里面设置对象类型的值
    public void testInsertCollectionBean1(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
        //获取配置创建的对象
        Stu1 stu=context.getBean("stu1",Stu1.class);
        System.out.println(stu);
    }



    @Test //测试集合属性的注入  命名空间 提取公共部分
    public void testInsertCollectionBean2(){
        //加载spring配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("beans1.xml");
        //获取配置创建的对象
        Library library=context.getBean("library",Library.class);
        System.out.println(library);
    }


    /**
     * 	Spring中有两种bean，一种是普通的bean，另外一种是工厂bean（FactoryBean）
     * 	普通bean：在配置文件中定义bean类型（也就是class属性值对应路径下的bean）就是返回类型
     * 	工厂bean：在配置文件定义bean类型可以和返回类型不一样
     */
    // 直接这么测试   返回的类型还是用   MyBean 会报错
    @Test
    public void testCollection2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        MyBean myBean = context.getBean("MyBean", MyBean.class);
        System.out.println(myBean);
    }
    @Test
    public void testCollection3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        //工厂bean返回的类型  和  工厂类型不一致
        //MyBean myBean = context.getBean("MyBean", MyBean.class);
        //System.out.println(myBean);
        Course course = context.getBean("MyBean", Course.class);
        System.out.println(course);
    }




    @Test //默认工厂模式返回的是单例的bean
    public void testDefaultBeanScop(){
        BeanFactory context = new ClassPathXmlApplicationContext("factory_bean.xml");
        Book book = context.getBean("book",Book.class);
        System.out.println(book);
        Book book1 = context.getBean("book",Book.class);
        System.out.println(book1);
    }
    @Test //
    public void testDefaultBeanScop1(){
        BeanFactory context = new ClassPathXmlApplicationContext("factory_bean.xml");
        Book book = context.getBean("book1",Book.class);
        Book book1 = context.getBean("book1",Book.class);
        System.out.println(book + "\n"+ book1);
    }




    @Test //bean的生命周期
    public void testBeanLife(){
        ApplicationContext context = new ClassPathXmlApplicationContext("factory_bean.xml");
        Order1 order = context.getBean("orders", Order1.class);
        System.out.println("第四步--获取创建bean实例对象~");
        System.out.println("第五步--使用bean实例对象~"+order);
        //手动销毁因为使用的是 ApplicationContext接口的子接口实现类的方法 因此强转
        ((ClassPathXmlApplicationContext)context).close();
        //context.close();//可以直接修改上面的接口为ClassPathXmlApplicationContext
    }





    @Test //测试xml形式的 手动装配
    public void xmlautowired(){
        ApplicationContext context = new ClassPathXmlApplicationContext("autowired.xml");
        Emp1 emp = context.getBean("emp", Emp1.class);
        System.out.println(emp);
    }
    @Test //测试xml形式的 自动装配 byName
    public void xmlautowired1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("autowired.xml");
        Emp1 emp = context.getBean("emp1", Emp1.class);
        System.out.println(emp);
    }
    @Test //测试xml形式的 自动装配 byType
    public void xmlautowired2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("autowired.xml");
        Emp1 emp = context.getBean("emp2", Emp1.class);
        System.out.println(emp);
    }

}
